#ifndef JANNA_LIBS_EXTENSIONSYSTEM_IPLUGIN_H_
#define JANNA_LIBS_EXTENSIONSYSTEM_IPLUGIN_H_

#include <QList>
#include <QMap>
#include <QObject>
#include <QString>
#include <QVariant>

#include "janna/libs/utils/pubsub.h"

namespace janna {
class PluginMetadataSubscribe;
/**
 * @brief 插件元数据
 */
class PluginMetadata : public QObject {
    Q_OBJECT
public:
    PluginMetadata()           = default;
    ~PluginMetadata() override = default;

public:
    [[nodiscard]] QString id() const;
    void                  id(QString&& id);

    [[nodiscard]] QString version() const;
    void                  version(QString&& version);

    [[nodiscard]] QString author() const;
    void                  author(QString&& author);

    [[nodiscard]] QString name() const;
    void                  name(QString&& name);

    [[nodiscard]] QList<PluginMetadataSubscribe*> subscribes() const;

private:
    /**
     * @brief 插件 id
     */
    QString m_id;
    /**
     * @brief 插件版本
     */
    QString m_version;
    /**
     * @brief 插件作者
     */
    QString m_author;
    /**
     * @brief 插件名称
     */
    QString m_name;
    /**
     * @brief 插件订阅消息
     */
    QList<PluginMetadataSubscribe*> m_subscribes;
};

/**
 * @brief 插件订阅消息元数据
 * 
 */
class PluginMetadataSubscribe : public QObject {
    Q_OBJECT
public:
    PluginMetadataSubscribe()           = default;
    ~PluginMetadataSubscribe() override = default;

public:
    [[nodiscard]] QString source() const;
    void                  source(QString&& source);

    [[nodiscard]] QString topic() const;
    void                  topic(QString&& topic);

    [[nodiscard]] QString publish() const;
    void                  publish(QString&& publish);

private:
    /**
     * @brief 消息来源
     */
    QString m_source;
    /**
     * @brief 消息主题
     */
    QString m_topic;
    /**
     * @brief 消费消息后发送的消息
     */
    QString m_publish;
};

/**
 * @brief 插件接口. 所有插件都应该继承此接口
 */
class JannaPluginInterface {
public:
    virtual ~JannaPluginInterface() = default;
    /**
     * @brief 插件名称
     * 
     * @return 插件名称 
     */
    virtual QString pluginName() = 0;
    /**
     * @brief 插件版本
     * 
     * @return  插件版本
     */
    virtual QString pluginVersion() = 0;
    /**
     * @brief 插件作者
     * 
     * @return 插件作者
     */
    virtual QString author() = 0;
    /**
     * @brief 消息响应
     * 
     * @param point 消息主题
     * @param param 消息参数
     * @return QMap<QString, QVariant> 响应消息后需要发布的消息参数
     */
    virtual QMap<QString, QVariant> handler(const JannaTopic& point, const QMap<QString, QVariant>& param) = 0;

    /**
     * @brief 插件初始化
     * 
     * @param error_message 初始化报错时的消息
     * @return true 初始化成功
     * @return false 初始化失败
     */
    virtual bool initialize(QString* error_message) = 0;
    /**
     * @brief 初始化消息订阅
     * 
     * @param points 需要订阅的消息列表
     */
    void initPoints(QList<JannaTopic>&& points);

    void initPluginMetadata(PluginMetadata* metadata);

    /**
     * @brief 过滤消息,只响应 metadata 中订阅的消息
     * 
     * @param topic 主题
     * @param param 参数
     */
    void pointHandlerInterceptor(const JannaTopic& topic, const QMap<QString, QVariant>& param);

protected:
    /**
     * @brief 插件订阅的主题列表
     */
    QList<JannaTopic> m_points;
    /**
     * @brief 插件元数据
     */
    PluginMetadata* m_plugin_metadta{nullptr};
};

};  // namespace janna

QT_BEGIN_NAMESPACE

#define JannaPluginInterface_iid "com.laolang.janna.JannaPluginInterface"

Q_DECLARE_INTERFACE(janna::JannaPluginInterface, JannaPluginInterface_iid)
QT_END_NAMESPACE

#endif